package cn.com.messageManager;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.nio.charset.Charset;
import java.util.Vector;
//import org.apache.mina.core.future.WriteFuture;
import org.apache.mina.core.session.IoSession;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import cn.com.broad.Board_seat;
import com.server.Board_Table;
import com.server.thread.ConnectionThread;

   
public class mySocket 
{
	private static Logger logger = LoggerFactory.getLogger(mySocket.class);
  //头长
    private final int HEADLEN=9;
    //
    private BufferEncrypt myBe=new BufferEncrypt();
    //调试开关
    //private boolean on_off = false;
	//构造
    public mySocket()
    {
    }
    /**
     * 写头
     * @param _cmd
     * @param _ver
     * @param _subVer
     */
    
    public void writeHeader(int _cmd,byte _ver,byte _subVer, Vector<Byte> vv)
    {
    	 
    	String ss=new String("IC");
    	try
    	{
    		byte[]	tempByte=ss.getBytes("utf-8");
    		if( tempByte.length == 2 )
        	{
        	    for(int i=0;i<2;i++)
        	    {
        	    	vv.add(tempByte[i]);
        	    }
        	}
        	else
        	{
        		System.out.println("写");
        	}
    	}catch(Exception e)
    	{
    	    logger.error("  writeHeader  出错：", e.getMessage());
    	}
    	
    	
    	writeCmd(_cmd,vv);
    	writeVer(_ver,vv);
    	writeSubver(_subVer,vv);
    	
    	
    	vv.add((byte)0); // 头里下表为6
    	vv.add((byte)0); // 头里下表为7
    	//writeBodyLen(0);
    	writeCode((byte)1,vv);
    }
    
    //写编码
    public void writeCode(byte _byte,Vector<Byte> vv)
    {
    	vv.add(_byte);
    	
    }
    
    //写放命令
    public  void writeCmd(int _cmd,Vector<Byte> vv)
    {
    	
//    	System.out.println("发送命令号："+Integer.toHexString(_cmd));
    	byte[] tempByte=new byte[2];
    	try
    	{
        	tempByte=shortToByteArray(_cmd);
        	
        	
        	vv.add(tempByte[1]);
        	vv.add(tempByte[0]);
        	
    	}catch(Exception e)
    	{
    		System.out.println("  writeCmd  出错："+ e.getMessage());
    	}
    }
    
    //写版本号
    public  void writeVer(byte _ver,Vector<Byte> vv)
    {
        vv.add(_ver);
     
    	
    }

    public void writeSubver(byte _subVer,Vector<Byte> vv)
    {
    	vv.add(_subVer);
    	
    }
    
    //写包长
    public  void writeBodyLen(int _bodyLen,Vector<Byte> vv)
    {
        byte[] tempByte=new byte[2];
        try
        {
    	    tempByte=shortToByteArray(_bodyLen);
    	    vv.set(6, tempByte[1]) ;
    	    vv.set(7, tempByte[0]) ;
        }catch(Exception e)
        {
        	System.out.println("  writeBodyLen  出错："+ e.getMessage());
        }
     
    }
    
    //写2位整型
    public void writeShort(int _short , Vector<Byte> vv)
    {
    	try
        {
    	  byte[] tempByte= shortToByteArray(_short);
    	 
    	 for(int i = tempByte.length-1;i>=0;i--)
    	  {

    		  vv.add(tempByte[i]);
    		 
    	  }

        }catch(Exception e)
        {
        	System.out.println("  writeShort  出错："+ e.getMessage());
        }
    }
    

    
    //写整型
    public void writeInt(int _int, Vector<Byte> vv)
    {
        try
        {
    	  byte[] tempByte= intToByteArray(_int);
    	 
    	  for(int i=tempByte.length-1;i>=0;i--)
    	  {
    		  vv.add(tempByte[i]);
    	  }
        }catch(Exception e)
        {
        	System.out.println("  writeInt  出错："+ e.getMessage());
        }
    	  
    }

    //写浮点型
    public void writeFloat(double _int, Vector<Byte> vv)
    {
        try
        {
    	  byte[] tempByte= floatToByteArray(_int);
    	 
    	  for(int i=tempByte.length-1;i>=0;i--)
    	  {
    		  vv.add(tempByte[i]);
    	  }
        }catch(Exception e)
        {
        	System.out.println("  writeInt  出错："+ e.getMessage());
        }
    	  
    }

    //写英文字符
    public void writeEngString(String _string, Vector<Byte> vv)
    {
          byte[] tempByte=_string.getBytes();
    	  int tempLen=tempByte.length;
    	  for(int i=0;i<tempLen;i++)
    	  {
    		  vv.add(tempByte[i]);
    		 
    	  }

    }

    //写中文字符
    public void writeChiString(String _string, Vector<Byte> vv)
    {
    	  String tempString =_string+"\0";
          byte[] tempByte= tempString.getBytes(Charset.forName("utf-8"));
    	  int tempLen = tempByte.length;
    	  this.writeShort(tempLen, vv); //加入数组长度
    	  for(int i = 0 ; i < tempLen;i++)
    	  {
    		 vv.add(tempByte[i]);
    	  }
    }
    
    //写字节
    public void writeByte(byte _byte, Vector<Byte> vv)
    {
    	vv.add(_byte);
    }
    
    
    //写结尾
    public  void writeEnd(Vector<Byte> vv)
    {
    	int tempInt=vv.size()-HEADLEN;
    	writeBodyLen(tempInt,vv);
    }

    //发送单命令
    public  void writeSend(IoSession _os, Vector vv)
    {
        byte[] tempByte=new byte[vv.size()];
        for(int i=0; i < vv.size(); i++)
        {
        	tempByte[i]=(Byte) vv.get(i);
        }
    	tempByte=myBe.EncryptBuffer(tempByte,HEADLEN,tempByte.length,BufferEncrypt.m_SendByteMap);
    	try
    	{
    	    _os.write(tempByte);
    	}catch(Exception e)
    	{
    		logger.error("  writeSend  出错：{}", e.getMessage());
    	}
    }
    
    /*
     * 发送广播命令
     */
    public  void CastSend( Vector vv ,Board_Table table,Board_seat seat)
    {
        byte[] tempByte=new byte[vv.size()];
        for(int i=0; i < vv.size(); i++)
        {	
        	tempByte[i]=(Byte) vv.get(i);
        }
    	tempByte=myBe.EncryptBuffer(tempByte,HEADLEN,tempByte.length,BufferEncrypt.m_SendByteMap);
    	try
    	{	//所有的在线用户
    		for(int i = table.getThreadpool().size()-1;i >= 0; i++ ){
    			
    			IoSession session = table.getThreadpool().get(i).getSession();
    			if(session == null){
    				continue;
    			}
    			if(session.getAttribute("ownseat") != null
    			&& session.getAttribute("ownseat").equals(seat))
    			{
    			continue;
    			}
    			session.write(tempByte);
    		}
    	}catch(Exception e)
    	{
    		logger.error("  CastSend  出错：", e.getMessage());
    	}
    }
    
    /*
     * 发送广播活动命令
     */
    
    public  void CastActiveSend( Vector vv ,Board_Table table)
    {
    	logger.info("发送广播送息");
        byte[] tempByte=new byte[vv.size()];
        for(int i=0; i < vv.size(); i++)
        {	
        	tempByte[i]=(Byte) vv.get(i);
        }
    	tempByte=myBe.EncryptBuffer(tempByte,HEADLEN,tempByte.length,BufferEncrypt.m_SendByteMap);
    	try
    	{	
    		for(int i = 0;i<table.getThreadpool().size();i++)
    		{
    			logger.info("广播次数："+i);
    			try{
	    			if(table.getThreadpool().get(i).getSession() == null||table.getThreadpool().get(i).getSession().getAttribute("ownseat") == null)
	    			{
	    				continue;
	    			}
    			}
    			catch(Exception e)
    			{
    				e.printStackTrace();
    				continue;
    			}
    			
    			table.getThreadpool().get(i).getSession().write(tempByte);
    		}
    	}catch(Exception e)
    	{
    		logger.error("  CastSend  出错：", e.getMessage());
    	}
    }
    
    /*
     * 发送广播命令
     */
    public  void CastSend( Vector vv ,Board_Table table)
    {
    	logger.info("发送广播送息");
        byte[] tempByte=new byte[vv.size()];
        for(int i=0; i < vv.size(); i++)
        {	
        	tempByte[i]=(Byte) vv.get(i);
        }
    	tempByte=myBe.EncryptBuffer(tempByte,HEADLEN,tempByte.length,BufferEncrypt.m_SendByteMap);
    	try
    	{	
    		for(int i = 0;i<table.getThreadpool().size();i++)
    		{
    			logger.info("广播次数："+i);
    			try{
	    			if(table.getThreadpool().get(i).getSession() == null)
	    			{
	    				continue;
	    			}
    			}
    			catch(Exception e)
    			{
    				e.printStackTrace();
    				continue;
    			}
    			
    			table.getThreadpool().get(i).getSession().write(tempByte);
    		}
    	}catch(Exception e)
    	{
    		logger.error("  CastSend  出错：", e.getMessage());
    	}
    }
    
    
    
    /*
     * 发送广播命令
     */
    public  void CastSendPass( Vector vv ,Board_Table table,ConnectionThread thread)
    {
        byte[] tempByte=new byte[vv.size()];
        for(int i=0; i < vv.size(); i++)
        {	
        	tempByte[i]=(Byte) vv.get(i);
        }
    	tempByte=myBe.EncryptBuffer(tempByte,HEADLEN,tempByte.length,BufferEncrypt.m_SendByteMap);
    	try
    	{	
    		
    		for(int i = 0;i<table.getThreadpool().size();i++){
    			
    			try{
    			if(table.getThreadpool().get(i).getSession() == null)
    			{
    				System.out.println(table.getThreadpool().get(i).getUser().getUser_id()+"......got the session is null");
    				continue;
    			}
    			if(table.getThreadpool().get(i).getUser().getUser_name().equals(thread.getUser().getUser_name())){
    				//WriteFuture future = table.getThreadpool().get(i).getSession().write(tempByte);
    				
    			}else if(table.getThreadpool().get(i).getSeat() == null){
    				continue;
    			}
    			}
    			catch(Exception e)
    			{
    				continue;
    			}
    			// WriteFuture future = table.getThreadpool().get(i).getSession().write(tempByte);
    			//System.out.println(" "+future.getSession().getRemoteAddress()+".....cn.com.messageManager..........CastSend..................cast to all user.."+future.isWritten());
    		}
    	}catch(Exception e)
    	{
    		logger.error("  CastSendPass  出错：", e.getMessage());
    	}
    }
    
    
    /*
     * 发送广播命令
     * 除了自己，其他的都进行广播
     */
    public  void castSenddeside( Vector vv ,Board_Table table,ConnectionThread thread )
    {
        byte[] tempByte=new byte[vv.size()];
        for(int i=0; i < vv.size(); i++)
        {	
        	tempByte[i]=(Byte) vv.get(i);
        }
    	tempByte=myBe.EncryptBuffer(tempByte,HEADLEN,tempByte.length,BufferEncrypt.m_SendByteMap);
    	try
    	{	
    		for(int i = 0;i<table.getThreadpool().size();i++){
    			if(table.getThreadpool().get(i).equals(thread)){
//    				System.out.println("比对线程发现是自己，就不调用进行广播！！！！！！");
    				continue;
    			}
    			if(table.getThreadpool().get(i).getSession() == null){
    				continue;  //   可能是用户掉线
    			}
    			table.getThreadpool().get(i).getSession().write(tempByte);
    		}
    	}catch(Exception e)
    	{
    		logger.error("  castSenddeside  出错：", e.getMessage());
    		
    	}
    }
    
    
    //整型转化为字节型2位
    public static byte[] shortToByteArray(int i) throws Exception 
    {    
        ByteArrayOutputStream buf = new ByteArrayOutputStream();    
        DataOutputStream out = new DataOutputStream(buf);    
        out.writeShort(i);    
        byte[] b = buf.toByteArray();    
        out.close();    
        buf.close();    
        return b;    
    }  
    //浮点型转化为字节型4位	
    public static byte[] floatToByteArray(double i) throws Exception 
    {    
        ByteArrayOutputStream buf = new ByteArrayOutputStream();    
        DataOutputStream out = new DataOutputStream(buf);    
//        out.writeFloat(i); 
        out.writeDouble(i);
        byte[] b = buf.toByteArray();    
        out.close();    
        buf.close();    
        return b;    
    }  
    	
    //整型转化为字节型4位	
   public static byte[] intToByteArray(int i) throws Exception 
   {    
       ByteArrayOutputStream buf = new ByteArrayOutputStream();    
       DataOutputStream out = new DataOutputStream(buf);    
       out.writeInt(i);    
       byte[] b = buf.toByteArray();    
       out.close();    
       buf.close();    
       return b;    
   }  
 
   //字节2位转换为整型
   public static int toIntegerD(byte[] b) 
   {
       int s = 0;
       for (int i = 0; i < 2; i++)
       {
           if (b[i] > 0)
               s = s + b[i];
           else
               s = s + 256 + b[i];
           s = s * 256;
       }
       if (b[3] > 0)
           s = s + b[3];
       else
           s = s + 256 + b[3];
       return s;
   }
   
   
    //解析头 0解析没有通过 1解析正常 2 解析策略文件
   public byte[] parseHeader(byte[] array)
   {
	   byte[] headerPacket=new byte[HEADLEN];
	   
	   for(int i=0;i<9;i++){
		   headerPacket[i]=array[i];
	   }
	   
	   String headLag="IC";
	   byte[] check=headLag.getBytes();
	   
	   //String secrity="<policy-f";
	  // byte[] checkSecity = secrity.getBytes();
	   
	   if(check[0] == headerPacket[0] && check[1] == headerPacket[1])
	   {
		   return headerPacket;
	   }
	   return null;
   }
   
   
   
   //获得命令号 -1为错误的命令号
   public int getCmd(byte[] headerPacket)
   {
	   if(headerPacket==null)
	   {
		   return -1;
	   }
	   else
	   {
		   int cmd_g = headerPacket[2];
		   int cmd_x = headerPacket[3];
		   int cmd = cmd_x/16*16*16*16+cmd_x%16*16*16+cmd_g/16*16+cmd_g%16;
		   return cmd;
	   }
   }
   
   //获得版本号
   public int getVer(byte[] headerPacket)
   {
	   if(headerPacket == null)
	   {
		   return -1;
	   }
	   else
	   {
		   int ver = headerPacket[4];
		   return ver;
	   }
   }
   
   //获得Sub版本号
   public int getSubver(byte[] headerPacket)
   {
	   if(headerPacket == null)
	   {
		   return -1;
	   }
	   else
	   {
		   int subVer = headerPacket[5];
		   return subVer;
	   }
   }
   
   public int getPackLen(byte[] headerPacket )
   {
	   if(headerPacket == null)
	   {
		   return -1;
	   }
	   else
	   {
		   int len_x = headerPacket[7];
		   int len_g = headerPacket[6];
		   int bodyLen = len_x/16*16*16*16+len_x%16*16*16+len_g/16*16+len_g%16;
		   return bodyLen;
	   }
   }
   
   public int getCode(byte[] headerPacket)
   {
	   if(headerPacket==null)
	   {
		   return -1;
	   }
	   else
	   {
		   int code=headerPacket[8];
		   return code;
	   }
   }
   
   public byte[] parseBody(byte[] array,int _len,int _code)
   {
	   byte[] receivePacket=new byte[1024];
	   for(int i = 9;i < 9+_len ;i++){
		   receivePacket[i-9]=array[i];
	   }
	   receivePacket=myBe.CrevasseBuffer(receivePacket, 0,_len,_code, BufferEncrypt.m_RecvByteMap);
	   return receivePacket;
   }

   //读指字长度字符
   public String readString(byte[] _packet,int _len,int _pos)
   {
	   byte[] tempstring=new byte[_len];
	   for(int i=0;i < _len;i++)
	   {
		   tempstring[i]=_packet[_pos];
	       _pos++;
	   }
	   return new String(tempstring,Charset.forName("utf-8"));
   }

   // 读4位整型
   public int readInt(byte[] _packet,int _pos)
   {
	   byte[] tempInt=new byte[4];
	   for(int i=0;i<4;i++)
	  {
		  tempInt[i] = _packet[_pos];
		 // System.out.println("<>"+_packet[_pos]);
	      _pos++;
	  }
	   return toInt(tempInt);
   }
   
   //读二位整型
   public int readShort(byte[] _packet,int _pos)
   {
	   byte[] tempInt=new byte[2];
	   for(int i=0;i<2;i++)
	  {
		  tempInt[1-i]=_packet[_pos];
//		  if(on_off)
//		  System.out.println("输出细节"+tempInt[1-i]);
	      _pos++;
	  }
//	   if(on_off)
//	   System.out.println("输出短整型:"+toShort(tempInt));
	   return toShort(tempInt);
   }

//字节2位转换为整型
   public static int toShort(byte[] _b) 
   {
	   int s = -1;
	   try
	   {
		   ByteArrayInputStream buf = new ByteArrayInputStream(_b);    
		   DataInputStream out = new DataInputStream(buf); 
		   s=out.readShort();
       
	   }catch(Exception e)
	   {
			logger.error("  toShort  出错：", e.getMessage());
	   }
	   return s;
		}

	public static int toInt(byte[] _b) 
	{
		int targets = (_b[0] & 0xff) | ((_b[1] << 8) & 0xff00)| ((_b[2] << 24) >>> 8) | (_b[3] << 24); 
		return targets; 
	}

   //  读1位字节
   public int readByte(byte[] _packet,int _pos)
   {
	   int tempByteInt=0;
	   tempByteInt=_packet[_pos];
	   _pos++;
	   return tempByteInt;
   }
}
